Тест. Автокорреляция и стационарность


In [1]:
from __future__ import division

import numpy as np
import pandas as pd

import statsmodels.api as sm

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"


C:\ProgramData\Anaconda3\envs\python2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
  from pandas.core import datetools

In [2]:
#Reading milk data
milk = pd.read_csv('monthly-milk-production.csv', ';', index_col=['month'], parse_dates=['month'], dayfirst=True)
milk.info()


<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 168 entries, 1962-01-01 to 1975-12-01
Data columns (total 1 columns):
milk    168 non-null int64
dtypes: int64(1)
memory usage: 2.6 KB

In [3]:
milk.head()


Out[3]:
milk
month
1962-01-01 589
1962-02-01 561
1962-03-01 640
1962-04-01 656
1962-05-01 727

In [4]:
_ = plt.plot(milk.index, milk.values)



In [5]:
sm.tsa.stattools.adfuller(milk.values.flatten())


Out[5]:
(-1.3038115874221228,
 0.62742670860303473,
 13L,
 154L,
 {'1%': -3.4735425281962091,
  '10%': -2.5768780536346769,
  '5%': -2.880497674144038},
 1115.1730447395112)

Часто, когда вы имеете дело с величинами, представляющими собой сумму значений показателя за каждый день или за каждый рабочий день, имеет смысл перед началом прогнозирования поделить весь ряд на число дней в периоде. Например, если поделить ряд с объёмом производства молока на одну корову на число дней в месяце, полученная величина будет меняться более плавно, и для неё легче будет построить прогнозирующую модель.

Корректно определить число дней в месяце можно с помощью свойства days_in_month у индекса ряда или функции monthrange из пакета calendar. Используйте число дней в месяце для того, чтобы вычислить новый показатель — среднее дневное число полученного молока на одну корову. Постройте график этого ряда и убедитесь, что он стал более гладким.


In [6]:
milk['daily'] = milk.milk.values.flatten() / milk.index.days_in_month
_ = plt.plot(milk.index, milk.daily)



In [7]:
milk.daily.values.sum()


Out[7]:
4166.3266618994658

Для ряда со средним дневным количеством молока на корову из предыдущего вопроса давайте с помощью критерия Дики-Фуллера подберём порядок дифференцирования, при котором ряд становится стационарным.

Дифференцирование можно делать так:

milk.daily_diff1 = milk.daily - milk.daily.shift(1)

Чтобы сделать сезонное дифференцирование, нужно изменить значение параметра у функции shift:

milk.daily_diff12 = milk.daily - milk.daily.shift(12)

При дифференцировании длина ряда сокращается, поэтому в части строк в новой колонке значения будут не определены (NaN). Подавая полученные столбцы на вход критерию Дики-Фуллера, отрезайте неопределённые значения, иначе вы получите неопределённый достигаемый уровень значимости.


In [18]:
milk.daily_diff1 = milk.daily - milk.daily.shift(1)
_ = plt.plot(milk.index, milk.daily_diff1)



In [29]:
sm.tsa.stattools.adfuller(milk.daily_diff1.dropna())


Out[29]:
(-2.7594694762289111,
 0.064300546541746925,
 11L,
 155L,
 {'1%': -3.4732590518613002,
  '10%': -2.5768120811654525,
  '5%': -2.8803740821053339},
 -1.153997338105512)

In [19]:
milk.daily_diff12 = milk.daily - milk.daily.shift(12)
_ = plt.plot(milk.index, milk.daily_diff12)



In [30]:
sm.tsa.stattools.adfuller(milk.daily_diff12.dropna())


Out[30]:
(-2.159486093288808,
 0.22127672658830372,
 12L,
 143L,
 {'1%': -3.4769274060112707,
  '10%': -2.5776654080884152,
  '5%': -2.8819726324025625},
 -25.225679141303317)

In [20]:
milk.daily_diff12_1 = milk.daily_diff12 - milk.daily_diff12.shift(1)
_ = plt.plot(milk.index, milk.daily_diff12_1)



In [31]:
sm.tsa.stattools.adfuller(milk.daily_diff12_1.dropna())


Out[31]:
(-5.481326334796929,
 2.2808455518037136e-06,
 11L,
 143L,
 {'1%': -3.4769274060112707,
  '10%': -2.5776654080884152,
  '5%': -2.8819726324025625},
 -20.90513750989237)

Для стационарного ряда из предыдущего вопроса постройте график автокорреляционной функции.


In [33]:
sm.graphics.tsa.plot_acf(milk.daily_diff12_1.dropna().values.squeeze(), lags=50),


Out[33]:
(<matplotlib.figure.Figure at 0x1130f5f8>,)

In [34]:
sm.graphics.tsa.plot_pacf(milk.daily_diff12_1.dropna().values.squeeze(), lags=50);



In [ ]: